﻿#include "ssThread.h"

namespace StarSeeker
{

ssThread::ssThread()
	:m_hThread(0),
	 m_ThreadId(0)
{
}

ssThread::~ssThread()
{
	WaitForExit();
}

bool ssThread::StartThread(ssThreadFunc_t func)
{
	if (m_hThread) return false;
#ifdef SS_USE_BOOST_THREAD
	m_hThread = new boost::thread(boost::bind(func));
#elif defined SS_USE_WINDOWS
	m_hThread = (HANDLE)_beginthreadex(0, 0, func, this, 0, 0);
	if (!m_hThread)
	{
		return false;
	}
#else
	if (::pthread_create(&m_hThread, 0, func, this))
	{
		return false;
	}
#endif
	return true;
}

void ssThread::WaitForExit()
{
	if ( !m_hThread ) return;
#ifdef SS_USE_BOOST_THREAD
	m_hThread->join();
	delete m_hThread;
#elif defined SS_USE_WINDOWS
	WaitForSingleObject(m_hThread, INFINITE);
	CloseHandle(m_hThread);
#else
	pthread_join(m_hThread, 0);
	pthread_detach(m_hThread);
#endif
	m_hThread = 0;
}

bool ssThread::IsRunning() const
{
	if ( 0==m_hThread ) return false;
#ifdef SS_USE_BOOST_THREAD
	return m_hThread->joinable();
#elif defined SS_USE_WINDOWS
	DWORD r = WaitForSingleObject(m_hThread, 0);
	if ( WAIT_TIMEOUT==r )
		return true;
	return false;
#else
	int kill_rc = pthread_kill(m_hThread, 0);
	if( ESRCH==kill_rc )
		return false;
	return true;
#endif
}

bool ssThread::Yields()
{
#ifdef SS_USE_BOOST_THREAD
	boost::this_thread::yield();
	return true;
#elif defined SS_USE_WINDOWS
	return ::SwitchToThread() == TRUE;
#else
	return ::pthread_yield() == 0;
#endif
}

void ssThread::Sleep(unsigned int ms)
{
#ifdef SS_USE_BOOST_THREAD
	boost::this_thread::sleep(boost::posix_time::milliseconds(ms));
#elif defined SS_USE_WINDOWS
	::Sleep(ms);
#else
	::usleep(ms*1000);
#endif
}

}
